package com.scalar.chiptrack.jasper.base;

import com.scalar.chiptrack.commons.Constants;
import com.scalar.chiptrack.commons.SessionKeys;
import com.scalar.chiptrack.utils.StringUtils;
import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.engine.export.JRHtmlExporter;
import net.sf.jasperreports.engine.export.JRHtmlExporterParameter;
import net.sf.jasperreports.engine.export.JRXlsExporter;
import net.sf.jasperreports.engine.export.JRXlsExporterParameter;
import net.sf.jasperreports.j2ee.servlets.ImageServlet;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletContext;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.File;
import java.util.Map;
import java.util.HashMap;
import java.util.Enumeration;

import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

/**
 *
 */
public class JasperReportsHelper {
    public static void exportReport(JasperPrint jasperPrint, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws IOException, JRException {
        String reportType = httpServletRequest.getParameter(Constants.REQUEST_PARAM_REPORT_TYPE);
        if (StringUtils.isNullOrEmpty(reportType)) {
            reportType = Constants.REPORT_TYPE_HTML;
        }
        PrintWriter out = httpServletResponse.getWriter();
        if (Constants.REPORT_TYPE_HTML.equalsIgnoreCase(reportType)) {
            httpServletResponse.setContentType("text/html");

            JRHtmlExporter exporter = new com.scalar.chiptrack.jasper.base.ChiptrackJRHtmlExporter();

            Integer jprintcnt = (Integer)httpServletRequest.getSession().getAttribute(SessionKeys.PARAM_JASPER_PRINT_COUNT);
            if(jprintcnt == null) {
                jprintcnt = 1;
            } else {
                jprintcnt = jprintcnt + 1;
            }
            httpServletRequest.getSession().setAttribute(SessionKeys.PARAM_JASPER_PRINT_COUNT, jprintcnt);

            String printSessionName = ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE + jprintcnt.toString();
            httpServletRequest.getSession().setAttribute(printSessionName, jasperPrint);

            exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
            exporter.setParameter(JRExporterParameter.OUTPUT_WRITER, out);
            exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, httpServletRequest.getContextPath() + "/jasper/image?" + "jrprint=" + printSessionName + "&image=");

            exporter.exportReport();
        }
    }

	public static ActionForward exportReport(JasperPrint jasperPrint, ActionMapping actionMapping, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws IOException, JRException {
        String reportType = httpServletRequest.getParameter(Constants.REQUEST_PARAM_REPORT_TYPE);
        if (StringUtils.isNullOrEmpty(reportType)) {
            reportType = Constants.REPORT_TYPE_HTML;
        }
        if (Constants.REPORT_TYPE_HTML.equalsIgnoreCase(reportType)) {
            httpServletResponse.setContentType("text/html");

			//httpServletRequest.setAttribute(Constants.REQUEST_PARAM_JASPER_PRINT, jasperPrint);
			return actionMapping.findForward("htmlView");
        } else if (Constants.REPORT_TYPE_PDF.equalsIgnoreCase(reportType)) {
			httpServletResponse.setContentType("application/pdf");
			httpServletResponse.setHeader("Content-Disposition", "attachment; filename=" + getAttachmentFileName(httpServletRequest) + ";");

			JasperExportManager.exportReportToPdfStream(jasperPrint, httpServletResponse.getOutputStream());
		} else if (Constants.REPORT_TYPE_EXCEL.equalsIgnoreCase(reportType)) {
			httpServletResponse.setContentType("application/vnd.ms-excel");
			httpServletResponse.setHeader("Content-Disposition", "attachment; filename=" + getAttachmentFileName(httpServletRequest) + ";");

			JRXlsExporter exporterXLS = new JRXlsExporter();
			exporterXLS.setParameter(JRXlsExporterParameter.JASPER_PRINT, jasperPrint);
			exporterXLS.setParameter(JRXlsExporterParameter.OUTPUT_STREAM, httpServletResponse.getOutputStream());
			exporterXLS.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.FALSE);
			exporterXLS.setParameter(JRXlsExporterParameter.IS_DETECT_CELL_TYPE, Boolean.TRUE);
			exporterXLS.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND, Boolean.FALSE);
			exporterXLS.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE);
			exporterXLS.exportReport();
		}

		return null;
    }

	public static JasperReport getJasperReport(HttpServletRequest httpServletRequest) throws JRException {
		String reportName = getReportName(httpServletRequest);
		ServletContext context = httpServletRequest.getSession().getServletContext();
		File reportFile = new File(context.getRealPath("/jasper_reports/jasper" + (reportName.startsWith("/") ? reportName : "/"+reportName) + ".jasper"));
        if (!reportFile.exists()) {
            throw new JRRuntimeException("File WebappReport.jasper not found. The report design must be compiled first.");
        }

        return (JasperReport) JRLoader.loadObject(reportFile.getPath());
	}

	public static String getReportName(HttpServletRequest httpServletRequest) {
		return httpServletRequest.getParameter(Constants.REQUEST_PARAM_REPORT_NAME);
	}

	public static String getJasperPrintSessionParamName(HttpServletRequest httpServletRequest, Boolean ignorePagination) {
		if(ignorePagination == null) {
			ignorePagination = Boolean.valueOf((httpServletRequest.getParameter(Constants.REQUEST_PARAM_IGNORE_PAGINATION)));
		}
		return ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE + "_" + JasperReportsHelper.getReportName(httpServletRequest) + "_" + (ignorePagination?"NO_PAGINATION":"WITH_PAGINATION");
	}

	public static String getReportType(HttpServletRequest httpServletRequest) {
		return httpServletRequest.getParameter(Constants.REQUEST_PARAM_REPORT_TYPE);
	}

	public static String getAttachmentFileName(HttpServletRequest httpServletRequest) {
		String reportName = getReportName(httpServletRequest);
		String reportType = getReportType(httpServletRequest);

		int idx = reportName.lastIndexOf('/');
		if(idx != -1) {
			reportName = reportName.substring(idx+1);
		}
		if(Constants.REPORT_TYPE_EXCEL.equalsIgnoreCase(reportType)) {
			reportName += ".xls";
		} else if (Constants.REPORT_TYPE_PDF.equalsIgnoreCase(reportType)) {
			reportName += ".pdf";
		} else {
			reportName += ".html";
		}

		return reportName;
	}

	public static Map getParamMap(HttpServletRequest request) {
		Map paramMap = new HashMap();
		Enumeration e = request.getParameterNames();
		while(e.hasMoreElements()) {
			String paramName = (String)e.nextElement();
			String[] paramValues = request.getParameterValues(paramName);

			paramMap.put(paramName, stringify(paramValues));
		}
		ServletContext context = request.getSession().getServletContext();
		paramMap.put(JRParameter.REPORT_FILE_RESOLVER, new JasperFileResolver(context.getRealPath("")));
		paramMap.put(JRParameter.IS_IGNORE_PAGINATION, Boolean.valueOf((String)paramMap.get(Constants.REQUEST_PARAM_IGNORE_PAGINATION)));
		return paramMap;
	}

	public static String stringify(String[] stringArr) {
		String result = null;
		if(stringArr != null && stringArr.length > 0) {
			StringBuilder sb = new StringBuilder();
			sb.append(",");
			for(String str: stringArr) {
				sb.append(str);
			}
			result = sb.substring(1);
		}
		return result;
	}
}
